/*
 * Copyright (c) 2013-2018 上海汇数数据. All rights reserved.
 * @(#) EnumValueAttributeConverter.java 2018-08-06 14:06
 */

package cn.jh.common.core.support.jpa;

import cn.jh.common.core.domain.EnumValue;

import javax.persistence.AttributeConverter;
import javax.persistence.PersistenceException;
import java.util.Objects;


/**
 * @author Fuchun
 * @since 1.0
 */
public abstract class EnumValueAttributeConverter<E extends EnumValue<V>, V> implements AttributeConverter<E, V> {

    protected final Class<E> enumClass;
    protected final E[] constants;
    protected final E defaultValue;

    protected EnumValueAttributeConverter(Class<E> enumClass, E defaultValue) {
        this(enumClass, enumClass.getEnumConstants(), defaultValue);
    }

    protected EnumValueAttributeConverter(Class<E> enumClass, E[] constants, E defaultValue) {
        this.enumClass = enumClass;
        this.constants = constants;
        this.defaultValue = defaultValue;
    }

    @Override
    public V convertToDatabaseColumn(E enumValue) {
        return enumValue == null ? null : enumValue.getValue();
    }

    @Override
    public E convertToEntityAttribute(V value) {
        if (value == null) {
            return defaultValue;
        }
        // 仅支持 数字、字符串表示
        if (value instanceof Number) {
            int v = ((Number) value).intValue();
            for (E constant : constants) {
                if (((Number) constant.getValue()).intValue() == v) {
                    return constant;
                }
            }
        } else if (value instanceof String) {
            String target = (String) value;
            for (E constant : constants) {
                if (Objects.equals(constant.getValue(), target)) {
                    return constant;
                }
            }
        } else {
            throw new PersistenceException("Not support other type unless Integer and String to " + enumClass);
        }
        return null;
    }
}
